package com.example.framework;

import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.example.objects.ContactObject;

public class ContactHelper extends HelperWithWebDriverBase {
	
	private Contacts contactModel;
	private int lastContactId;

	public ContactHelper(ApplicationManager manager) {
		super(manager);
		contactModel = getContacts();
		lastContactId = Integer.parseInt(manager.getHibernateHelper().getNextContactId());
	}
	
	public Contacts getContacts() {
		if (contactModel == null) {
			contactModel = manager.getHibernateHelper().getContacts();
		}
		return contactModel;
	}
	
	public Contacts getUiContacts() {
		HashSet<ContactObject> set = new HashSet<ContactObject>();		
		manager.getNavigationHelper().openMainPage();		
        List<WebElement> rows = getRowsWithDataFromTable("maintable", true);
        for (WebElement row : rows) {
            ContactObject contact = new ContactObject()
                .setFirstName(getFirstNameInRow(row))  
                .setLastName(getLastNameInRow(row))                      
                .setId(row.findElement(By.name("selected[]")).getAttribute("value"));
            set.add(contact);
        }
        return new Contacts(set);
	}

	public void initContactCreation() {
		click(By.linkText("add new"));
	}

	public void createContact(ContactObject contactObject) {
		manager.getNavigationHelper().openMainPage();
		initContactCreation();
		fillContactForm(contactObject, true);
		submitCreation();
		manager.getNavigationHelper().returnToHomePage(); 
		contactObject.setId("" + lastContactId);
		contactModel = contactModel.withAdded(contactObject);
		lastContactId = lastContactId +1;
	}
	
	public void removeContact(ContactObject contactObject) {
		manager.getNavigationHelper().openMainPage();
		initContactModification(contactObject);
		deleteContact();
		manager.getNavigationHelper().returnToHomePage();
		contactModel = contactModel.without(contactObject);
	}

	public void modifyContact(ContactObject oldContactObject, ContactObject newContactObject) {
		manager.getNavigationHelper().openMainPage();
		initContactModification(oldContactObject);
		fillContactForm(newContactObject, false);
		submitModification();
		manager.getNavigationHelper().returnToHomePage();
		contactModel = contactModel.without(oldContactObject).withAdded(newContactObject);
	}

	private void initContactModification(ContactObject contactObject) {
		click(By.xpath("//input[@value='"+contactObject.id+"']/ancestor::tr//*[@alt='Edit']"));
    }

	private void deleteContact() {
		click(By.xpath("(//input[@name='update'])[2]"));
	}

	public void fillContactForm(ContactObject contactObject,
			boolean isCreateGroup) {
		enter(By.name("firstname"), contactObject.firstName);
		enter(By.name("lastname"), contactObject.lastName);
		enter(By.name("address"), contactObject.address);
		enter(By.name("home"), contactObject.phoneHome);
		enter(By.name("mobile"), contactObject.phoneMobile);
		enter(By.name("work"), contactObject.phoneWork);
		enter(By.name("email"), contactObject.emailPrimary);
		enter(By.name("email2"), contactObject.emailSecondary);
		select(By.name("bday"), contactObject.bdayDay);
		select(By.name("bmonth"), contactObject.bdayMonth);
		enter(By.name("byear"), contactObject.bdayYear);

		if (isCreateGroup) {
			driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
			select(By.name("new_group"), contactObject.groupByIndex);
			driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		} else {
			if (manager.getNavigationHelper().isElementPresent(By.name("new_group"))) {
				throw new Error("Group dropdown list exists, but mustn't");
			}
		}

		enter(By.name("address2"), contactObject.addressSecondary);
		enter(By.name("phone2"), contactObject.phoneSecondary);
	}

	private String getFirstNameInRow(WebElement row) {
		return row.findElement(By.xpath(".//td[3]")).getText();
	}

	private String getLastNameInRow(WebElement row) {
		return row.findElement(By.xpath(".//td[2]")).getText();
	}

	private List<WebElement> getTableRows(String tableId) {
		return findElements(By.xpath(".//*[@id='" + tableId + "']/tbody/tr"));
	}

	protected List<WebElement> getRowsWithDataFromTable(String tableId, boolean doesLastRowNeedsToBeRemoved) {
		int rowsQuantity = getTableRows(tableId).size();
		if (doesLastRowNeedsToBeRemoved) {
			return getTableRows(tableId).subList(1, (rowsQuantity-1));
		} else {
			return getTableRows(tableId).subList(1, rowsQuantity);
		}
		
	}


}
